﻿using System;
using System.Collections.Generic;
using System.Xml;
using System.IO;

namespace xmlclass
{
    public class XMLoperationClass
    {

        private XmlDocument xd;
        private XmlElement root;
        public string filename { set; get; }

        public XMLoperationClass()
        {
            xd = new XmlDocument();
        }
        public XMLoperationClass(string xmlpath)
        {
            xd = new XmlDocument();
            filename = xmlpath;
            xd.Load(xmlpath);
            root = xd.DocumentElement;
        }

        public bool CreateRootNode(string name, bool isclear)
        {
            if (isclear) xd.RemoveAll();
            xd.CreateXmlDeclaration("1.0", "utf-8", "yes");
            //SaveToFile();
            XmlNode xn = xd.SelectSingleNode(name);
            if (xn == null)
            {
                XmlElement xe = xd.CreateElement(name);
                if (xe != null)
                {
                    xd.AppendChild(xe);
                    root = xe;
                }
                SaveToFile();
                return true;
            }
            else
            {
                root = xd.DocumentElement;
                return false;
            }
        }

        public bool CreateNodeValue(string name, bool isCoverNode)
        {
            if (root == null) return false;
            XmlNode x = root.SelectSingleNode(name);
            if ((x != null) && (isCoverNode))
            {
                XmlElement xe = xd.CreateElement(name);
                root.AppendChild(xe);
                SaveToFile();
                return true;
            }
            else
            {
                return false;
            }
        }

        public bool CreateNodeValue(string name, string attrName, string attrVal, bool isCoverNode, bool isCoverAttr)
        {
            if (root == null) return false;
            XmlNodeList x = root.SelectNodes(name);
            if ((x != null) && (isCoverNode))
            {
                foreach (XmlNode n in x)
                {
                    foreach (XmlAttribute a in n.Attributes)
                    {
                        if ((a.Name == attrName) && (a.Value == attrVal))
                        {
                            if (!isCoverAttr) return false;
                        }
                    }
                }
            }
            XmlElement xe = xd.CreateElement(name);
            xe.SetAttribute(attrName, attrVal);
            root.AppendChild(xe);
            SaveToFile();
            return true;
        }

        public bool CreateChildNodeValue(string parentname, string pname, string name, string id, string val)
        {
            XmlElement xe = xd.CreateElement(name);
            XmlNodeList xnl = root.SelectNodes(parentname);
            foreach (XmlNode x in xnl)
            {
                if (x.Name == pname)
                {
                    if (id != string.Empty) xe.SetAttribute(id, val);
                    x.AppendChild(xe);
                    SaveToFile();
                    return true;
                }
            }
            return false;
        }

        public bool SetAttribute(string nodename, string mname, string id, string val)
        {
            if (root == null) return false;
            XmlNodeList xnl = root.SelectNodes(nodename);
            foreach (XmlNode x in xnl)
            {
                if (mname == x.Name)
                {
                    foreach (XmlAttribute a in x.Attributes)
                    {
                        if (a.Name == id)
                        {
                            x.Attributes[id].Value = val;
                            SaveToFile();
                            return true;
                        }
                    }
                    XmlAttribute xa = xd.CreateAttribute(id);
                    xa.Value = val;
                    x.Attributes.SetNamedItem(xa);
                    SaveToFile();
                    return true;
                }
            }
            return false;
        }

        public bool SetAttribute(string nodename, string pid, string aname, string id, string val)
        {
            if (root == null) return false;
            XmlNodeList xnl = root.SelectNodes(nodename);
            foreach (XmlNode x in xnl)
            {
                XmlNode xn = x.Attributes.GetNamedItem(pid);
                if (xn != null)
                {
                    if (xn.Value == aname)
                    {
                        foreach (XmlAttribute a in x.Attributes)
                        {
                            if (a.Name == id)
                            {
                                x.Attributes[id].Value = val;
                                SaveToFile();
                                return true;
                            }
                        }
                        XmlAttribute xa = xd.CreateAttribute(id);
                        xa.Value = val;
                        x.Attributes.SetNamedItem(xa);
                        SaveToFile();
                        return true;
                    }
                }
            }
            return false;
        }

        public string GetAttributeValue(string nodename, string bname, string id)
        {
            if (root == null) return string.Empty;
            XmlNodeList xnl = root.SelectNodes(nodename);
            foreach (XmlNode x in xnl)
            {
                if (bname == x.Name)
                {
                    return x.Attributes[id].Value;
                }
            }
            return string.Empty;
        }

        public List<string> GetAttributeValues(string nodename)
        {
            List<string> ls = new List<string>();
            string tmp;
            if (root == null) return ls;
            foreach (XmlNode x in root.SelectNodes(nodename))
            {
                tmp = string.Empty;
                for (int i = 0; i < x.Attributes.Count; i++)
                {
                    tmp += x.Attributes[i].Name + "=" + x.Attributes[i].Value + "|";
                }
                tmp = tmp.Substring(0, tmp.Length - 1);
                ls.Add(tmp);
            }
            return ls;
        }

        public List<string> GetXmlNodeNames(string nodename)
        {
            List<string> ls = new List<string>();
            if (root == null) return ls;
            foreach (XmlNode x in root.SelectNodes(nodename))
            {
                if (x.HasChildNodes)
                {
                    foreach (XmlNode n in x.ChildNodes)
                    {
                        ls.Add(n.Name);
                    }
                }
            }
            return ls;
        }

        public bool SaveToFile()
        {
            if (root == null) return false;
            xd.Save(filename);
            return true;
        }

        public bool SaveToFile(string path)
        {
            if (root == null) return false;
            xd.Save(path);
            return true;
        }

        public bool GetRoot()
        {
            if (File.Exists(filename))
            {
                xd.Load(filename);
                root = xd.DocumentElement;
                return true;
            }
            else
            {
                return false;
            }
        }

    }
}